﻿using System.Diagnostics;
using RDF;

using stepengine = RDF.ifcengine;

#if _WIN64
using int_t = System.Int64;
#else
using int_t = System.Int32;
#endif

namespace DZJIFC.Model
{
    public enum GeometryType
    {
        AP242,
        IFC
    }



    public class Geometry : _geometry
    {
        public GeometryType Type { get; private set; }
        public List<IInstance> Instances = new List<IInstance>();



        #region Methods

        public Geometry(GeometryType type) 
        {
            Type = type;
        }

        protected void Calculate()
        {
            int_t iModel = GetModel();
            uint iVertexLength = GetVertexLength();

            // Format
            SetFormat(iModel);

            /* Geometry */

            int_t iSdaiModel = stepengine.sdaiGetInstanceModel(Instance);

            long iOwlInstance = 0;
            stepengine.owlBuildInstance(iSdaiModel, Instance, out iOwlInstance);

            Vertices = null;
            Indices = null;

            RDF.engine.CalculateInstance(iOwlInstance, out long iVerticesCount, out long iIndicesCount, out long iTransformationBufferSize);
            if ((iVerticesCount == 0) || (iIndicesCount == 0))
            {
                return;
            }

            Vertices = new float[iVertexLength * iVerticesCount];
            RDF.engine.UpdateInstanceVertexBuffer(iOwlInstance, Vertices);

            Indices = new int[iIndicesCount];
            RDF.engine.UpdateInstanceIndexBuffer(iOwlInstance, Indices);

            /* Conceptual faces*/

            ConceptualFacesCount = RDF.engine.GetConceptualFaceCnt(Instance);

            Debug.WriteLine("*** BEGIN INSTANCE");
            Debug.WriteLine("*** Vertices: {0}, Indices: {1}, Conc. Faces: {2}", iVerticesCount, iIndicesCount, ConceptualFacesCount);

            for (long iConceptualFaceIndex = 0; iConceptualFaceIndex < ConceptualFacesCount; iConceptualFaceIndex++)
            {
                long iStartIndexTriangles = 0;
                long iIndicesCountTriangles = 0;

                long iStartIndexLines = 0;
                long iIndicesCountLines = 0;

                long iStartIndexPoints = 0;
                long iIndicesCountPoints = 0;

                long iStartIndexConceptualFacePolygons = 0;
                long iIndicesCountConceptualFacePolygons = 0;

                long iValue = 0;
                long iConceptualFaceInstance = RDF.engine.GetConceptualFaceEx(Instance,
                    iConceptualFaceIndex,
                    out iStartIndexTriangles,
                    out iIndicesCountTriangles,
                    out iStartIndexLines,
                    out iIndicesCountLines,
                    out iStartIndexPoints,
                    out iIndicesCountPoints,
                    out iValue,
                    out iValue,
                    out iStartIndexConceptualFacePolygons,
                    out iIndicesCountConceptualFacePolygons);

                //Debug.WriteLine("*** Conceptual Face: {0}, Triangles: {1}, Lines: {2}, Conc. Face Polygons: {3}", 
                //    iConceptualFaceIndex,
                //    iIndicesCountTriangles,
                //    iIndicesCountLines,
                //    iIndicesCountConceptualFacePolygons);

                if (iIndicesCountTriangles > 0)
                {
                    var material = _material.Create(iConceptualFaceInstance);
                    if (material == null)
                    {
                        material = _material.GetFacesDefaultMaterial();

                    }

                    Triangles.Add(new _primitives(iStartIndexTriangles, iIndicesCountTriangles));

                    if (_dicMaterial2ConcFaces.ContainsKey(material))
                    {
                        _dicMaterial2ConcFaces[material].Add(new _face(iConceptualFaceIndex, iStartIndexTriangles, iIndicesCountTriangles));
                    }
                    else
                    {
                        var primitives = new List<_face>();
                        primitives.Add(new _face(iConceptualFaceIndex, iStartIndexTriangles, iIndicesCountTriangles));

                        _dicMaterial2ConcFaces[material] = primitives;
                    }
                }

                if (iIndicesCountConceptualFacePolygons > 0)
                {
                    ConcFacePolygons.Add(new _primitives(iStartIndexConceptualFacePolygons, iIndicesCountConceptualFacePolygons));
                }

                if (iIndicesCountLines > 0)
                {
                    var material = _material.Create(iConceptualFaceInstance);
                    if (material == null)
                    {
                        material = _material.GetLinesDefaultMaterial();

                    }

                    Lines.Add(new _primitives(iStartIndexLines, iIndicesCountLines));

                    if (_dicMaterial2ConcFaceLines.ContainsKey(material))
                    {
                        _dicMaterial2ConcFaceLines[material].Add(new _face(iConceptualFaceIndex, iStartIndexLines, iIndicesCountLines));
                    }
                    else
                    {
                        var primitives = new List<_face>();
                        primitives.Add(new _face(iConceptualFaceIndex, iStartIndexLines, iIndicesCountLines));

                        _dicMaterial2ConcFaceLines[material] = primitives;
                    }
                }

                if (iIndicesCountPoints > 0)
                {
                    var material = _material.Create(iConceptualFaceInstance);
                    if (material == null)
                    {
                        material = _material.GetLinesDefaultMaterial();

                    }

                    Points.Add(new _primitives(iStartIndexPoints, iIndicesCountPoints));

                    if (_dicMaterial2ConcFacePoints.ContainsKey(material))
                    {
                        _dicMaterial2ConcFacePoints[material].Add(new _face(iConceptualFaceIndex, iStartIndexPoints, iIndicesCountPoints));
                    }
                    else
                    {
                        var primitives = new List<_face>();
                        primitives.Add(new _face(iConceptualFaceIndex, iStartIndexPoints, iIndicesCountPoints));

                        _dicMaterial2ConcFacePoints[material] = primitives;
                    }
                }
            } // for (long iConceptualFace = ...

            Debug.WriteLine("*** END INSTANCE");
        }

        #endregion // Methods

    }
}
